home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
gnu
/
cvs-1_3.lha
/
cvs-1.3
/
src
/
release.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-29
|
5KB
|
220 lines
/*
* Release: "cancel" a checkout in the history log.
*
* - Don't allow release if anything is active - Don't allow release if not
* above or inside repository. - Don't allow release if ./CVS/Repository is
* not the same as the directory specified in the module database.
*
* - Enter a line in the history log indicating the "release". - If asked to,
* delete the local working directory.
*/
#include "cvs.h"
#ifndef lint
static char rcsid[] = "@(#)release.c 1.21 92/02/29";
#endif
#if __STDC__
static void release_delete (char *dir);
#else
static void release_delete ();
#endif /* __STDC__ */
static char *release_usage[] =
{
"Usage: %s %s [-d] modules...\n",
"\t-Q\tReally quiet.\n",
"\t-d\tDelete the given directory.\n",
"\t-q\tSomewhat quiet.\n",
NULL
};
static short delete;
int
release (argc, argv)
int argc;
char **argv;
{
FILE *fp;
register int i, c;
register char *cp;
int margc;
DBM *db;
datum key, val;
char *repository, *srepos;
char **margv, *modargv[MAXFILEPERDIR], line[PATH_MAX];
if (argc == -1)
usage (release_usage);
optind = 1;
while ((c = gnu_getopt (argc, argv, "Qdq")) != -1)
{
switch (c)
{
case 'Q':
really_quiet = 1;
/* FALL THROUGH */
case 'q':
quiet = 1;
break;
case 'd':
delete++;
break;
case '?':
default:
usage (release_usage);
break;
}
}
argc -= optind;
argv += optind;
if (!(db = open_module ()))
return (1);
for (i = 0; i < argc; i++)
{
/*
* If we are in a repository, do it. Else if we are in the parent of
* a directory with the same name as the module, "cd" into it and
* look for a repository there.
*/
if (isdir (argv[i]))
{
if (chdir (argv[i]) < 0)
{
if (!really_quiet)
error (0, 0, "can't chdir to: %s", argv[i]);
continue;
}
if (!isdir (CVSADM) && !isdir (OCVSADM))
{
if (!really_quiet)
error (0, 0, "no repository module: %s", argv[i]);
continue;
}
}
else
{
if (!really_quiet)
error (0, 0, "no such directory/module: %s", argv[i]);
continue;
}
repository = Name_Repository ((char *) NULL, (char *) NULL);
srepos = Short_Repository (repository);
/* grab module entry from database and check against short repos */
key.dptr = argv[i];
key.dsize = strlen (key.dptr);
val = dbm_fetch (db, key);
if (!val.dptr)
{
error (0, 0, "no such module name: %s", argv[i]);
continue;
}
val.dptr[val.dsize] = '\0';
if ((cp = index (val.dptr, '#')) != NULL) /* Strip out a comment */
{
do
{
*cp-- = '\0';
} while (isspace (*cp));
}
(void) sprintf (line, "%s %s", key.dptr, val.dptr);
line2argv (&margc, modargv, line);
margv = modargv;
optind = 1;
while (gnu_getopt (margc, margv, CVSMODULE_OPTS) != -1)
/* do nothing */ ;
margc -= optind;
margv += optind;
if (margc < 1)
{
error (0, 0, "modules file missing directory for key %s value %s",
key.dptr, val.dptr);
continue;
}
if (strcmp (*margv, srepos))
{
error (0, 0, "repository mismatch: module[%s], here[%s]",
*margv, srepos);
free (repository);
continue;
}
if (!really_quiet)
{
/*
* Now see if there is any reason not to allow a "Release" This
* is "popen()" instead of "Popen()" since we don't want "-n" to
* stop it.
*/
fp = popen ("cvs -n -q update", "r");
c = 0;
while (fgets (line, sizeof (line), fp))
{
if (index ("MARCZ", *line))
c++;
(void) printf (line);
}
(void) pclose (fp);
(void) printf ("You have [%d] altered files in this repository.\n",
c);
(void) printf ("Are you sure you want to release %smodule `%s': ",
delete ? "(and delete) " : "", argv[i]);
c = !yesno ();
if (c) /* "No" */
{
(void) fprintf (stderr, "** `%s' aborted by user choice.\n",
command_name);
free (repository);
continue;
}
}
/*
* So, we've passed all the tests, go ahead and release it. First,
* log the release, then attempt to delete it.
*/
history_write ('F', argv[i], "", argv[i], ""); /* F == Free */
free (repository);
if (delete)
release_delete (argv[i]);
}
close_module (db);
return (0);
}
/* We want to "rm -r" the repository, but let us be a little paranoid. */
static void
release_delete (dir)
char *dir;
{
struct stat st;
ino_t ino;
int retcode = 0;
(void) stat (".", &st);
ino = st.st_ino;
(void) chdir ("..");
(void) stat (dir, &st);
if (ino != st.st_ino)
{
error (0, 0,
"Parent dir on a different disk, delete of %s aborted", dir);
return;
}
run_setup ("%s -r", RM);
run_arg (dir);
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
error (0, retcode == -1 ? errno : 0,
"deletion of module %s failed.", dir);
}